
#ifndef PROJECTZ_NUSER_NCOMMAND_CS_REQ_EQUIP_H_
#define PROJECTZ_NUSER_NCOMMAND_CS_REQ_EQUIP_H_

#include "../../engine.h"

#include "../../User.h"

#include "../../NLogic/Bag.h"
#include "../../NLogic/Equip.h"
#include "../../NLogic/Item.h"
#include "../../NLogic/Static.h"
#include "../../NLogic/Function.h"

namespace ProjectZ { namespace NCommand { namespace NWorld {

class CS_REQ_EQUIP
{
public:
	static void OnExecute(User * pUser, ::Network::Packet * pPacket)
	{
		/*
		 * // 장비 장착 요청
			CS_REQ_EQUIP   0x0919
			{
					   uint8 equip_pos;            /// 장착위치
					   u8          u8bag_type;               /// 가방 타입
					   u64      u64item_seq;                /// 아이템 시퀀스
			}

			// 장비 장착 요청
			SC_REQ_EQUIP              0x091A
			{
					   s16       ack;                                      /// 1:장착 완료 ,  -1 장착실패
					   u16      slot_idx;
					   u64      u64item_seq;                /// 아이템 시퀀스
			}

		 *
		 */

		NLogic::Space * pSpace = pUser->GetSpace();
		if (NULL == pSpace)
		{
			DEBUGLOG("%s NULL == pSpace GID : %d", __FUNCTION__, pUser->GetUserSeq());
			return;
		}


		PREPARE_PACKET;
		int8_t equip_pos = 0;
		int8_t bag_type = 0;
		uint64_t u64item_seq;

		* pPacket >> equip_pos >> bag_type >> u64item_seq;

		NLogic::Bag * pBag = pUser->GetBag(static_cast<INVEN_BAG_TYPE>(bag_type));
		if (NULL == pBag)
		{
			DEBUGLOG("CS_REQ_EQUIP BAG IS NULL : %d", bag_type);
			return;
		}

		NLogic::Item * pItem = pBag->GetItem(u64item_seq);
		if (NULL == pItem)
		{
			SendErrorPacket(pUser, ACK_UNKNOWN_ERROR, bag_type, u64item_seq);
			return;
		}

		// 이름표 시간 만료 확인
		if (EnumItemEquipPosition::ITEM_EQUIP_POS_NAME_TAG == static_cast<EnumItemEquipPosition>(equip_pos))
		{
			if (time(NULL) > pItem->GetData().reg_date + (pItem->GetData().eff_value[0] * 60))
			{
				SendErrorPacket(pUser, ACK_TIME_EXPIRED_ITEM, bag_type, u64item_seq);
				return;
			}
		}

		if (pItem->GetData().level > (int)pUser->GetCharacterInfo().level)
		{
			SendErrorPacket(pUser, ACK_NOT_EQUIPPED_ITEM, bag_type, u64item_seq);
			return;
		}

		if (false == pUser->GetEquip()->AddItem(static_cast<EnumItemEquipPosition>(equip_pos), pItem))
		{
			DEBUGLOG("%s false == pUser->GetEquip()->AddItem(static_cast<EnumItemEquipPosition>(equip_pos), pItem) EQUIP POS : %d GID : %d", __FUNCTION__, equip_pos, pUser->GetUserSeq());
			SendErrorPacket(pUser, ACK_NOT_EQUIPPED_ITEM, bag_type, u64item_seq);
			return;
		}

		// 착용시 귀속 아이템인 경우
		if (pItem->GetData().buy_use == 1)
		{
			pItem->GetData().buy_use = 2;
			pItem->UpdateDatabaseItemInfo();
		}

		// 캐릭터 정보 갱신
		pUser->GetEquip()->UpdateCharacterInfo();
		pUser->FlushCharacterInfoCache();

		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		* pAck << static_cast<int16_t>(ACK_OK);
		* pAck << static_cast<uint8_t>(bag_type);
		* pAck << static_cast<uint64_t>(u64item_seq);
		pAck->MakePacket(CMD_SC_REQ_EQUIP);
		pUser->Send(pAck);

		const NLogic::Space::USERTREE & clsUserTree = pSpace->GetUserTree();
		std::for_each(clsUserTree.begin(), clsUserTree.end(), [&](const std::pair<const int, ProjectZ::User*>& pair) {
			if (NULL != pair.second && pair.first != pUser->GetUserSeq())
			{
				NLogic::NFunction::SendCharacterInfoSimple(pUser, pair.second);
			}
		} );
	}

	static void SendErrorPacket(User *pUser, int res, int bag_type, uint64_t u64item_seq)
	{
		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		* pAck << static_cast<int16_t>(res);
		* pAck << static_cast<uint8_t>(bag_type);
		* pAck << static_cast<uint64_t>(u64item_seq);
		pAck->MakePacket(CMD_SC_REQ_EQUIP);
		pUser->Send(pAck);
	}
};

} /*NWorld*/ } /*NCommand*/ } /*ProjectZ*/


#endif /* PROJECTZ_NUSER_NCOMMAND_CS_REQ_EQUIP_H_ */
